package vn.sunnet.backviet01.game.coloa.human.enemy;

import org.anddev.andengine.entity.modifier.MoveModifier;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.util.MathUtils;

import vn.sunnet.backviet01.game.coloa.constant.Constants;

public class FlatDragon extends MinisterEnemy {

	private static final long[] durationMove = { 80, 80, 80, 80, 80, 80, 80,
			80, 80, 80 };
	private static final long[] durationBeat = { 60, 60, 60, 60, 60, 60, 60,
		60, 60, 60, 60, 60, 60 };
	private static final long[] durationFireSkill = { 80, 80, 80, 80, 80, 80,
			1100 };

	private final TiledTextureRegion mAttackTextureRegion;

	private FlatDragonStates mState;
	private FlatDragonStates mLastState;

	private boolean isFire = false;
	private boolean isDodge = false;
	private boolean isMoveBack = false;

	private long countTimeDodge = 0;
	private long countDodge = 0;

	private long countTimeMoveBack = 0;
	private long timeMoveBack = 0;

	private int countShot = 0;

	private float xBack;
	private float yBack;

	public long lastCheckFire = 0;

	public FlatDragon(int tiledAttack, float pX, float pY,
			TiledTextureRegion pTiledTextureRegionMove,
			TiledTextureRegion pTiledTextureRegionAttack) {
		super(tiledAttack, pX, pY, pTiledTextureRegionMove);
		mAttackTextureRegion = pTiledTextureRegionAttack;
		this.animate(durationMove);
		resetInfor();
	}

	private void resetInfor() {
		mState = FlatDragonStates.MOVE;
		this.name = Constants.FLAT_DRAGON;
		isDodge = false;
		isMoveBack = false;
		countTimeDodge = 0;
		countShot = 0;
		countDodge = 0;
		isStun = false;
		timeStun = 0;
		isShot = false;
	}

	public void onManagedUpdate(float pSecondsElapsed) {
		if (isAllowChangeStatus) {
			if (mState == FlatDragonStates.DIE) {
				die();
			} else if (mState == FlatDragonStates.FIRE) {
				fire();
//				lockStun();
				countShot = 0;
			} else if (mState == FlatDragonStates.BEAT) {
				beat();
//				lockStun();
				countShot = 0;
			} else if (mState == FlatDragonStates.MOVE_BACK) {
				moveBack();
				countTimeMoveBack = System.currentTimeMillis();
			} else if (mState == FlatDragonStates.DODGE) {
				dodge(getCurrentTileIndex());
			} 
//			else if (isStun && startStun == 0) {
//				setStunAction();
//			}
			isAllowChangeStatus = false;
		} else if (mState != FlatDragonStates.DIE) {
			if (isMoveBack && this.hitPoints > 0) {
				if (countTimeMoveBack + timeMoveBack < System
						.currentTimeMillis()) {
					move();
					mState = FlatDragonStates.MOVE;
					isMoveBack = false;
					timeMoveBack = 0;
					countTimeMoveBack = 0;
				}
			} else if (isDodge && this.hitPoints > 0) {
				if (countTimeDodge + countDodge < System.currentTimeMillis()) {
					if (mLastState == FlatDragonStates.BEAT) {
						beat();
						mState = FlatDragonStates.BEAT;
					} else if (mLastState != FlatDragonStates.DIE) {
						move();
						mState = FlatDragonStates.MOVE;
					}
					isDodge = false;
					countDodge = 0;
					countTimeDodge = 0;
				}
			} 
//			else if (isStun && this.hitPoints > 0 && startStun > 0) {
//				if (timeStun + startStun < System.currentTimeMillis()) {
//					resetStunAction();
//				}
//			} 
			else if (mState == FlatDragonStates.FIRE
					&& this.getCurrentTileIndex() != tiledAttack) {
				isFire = false;
			} else if (mState == FlatDragonStates.BEAT
					&& this.getCurrentTileIndex() != tiledAttack)
				isAttack = false;

			this.revoverHP();
		}

		super.onManagedUpdate(pSecondsElapsed);
	}

//	private void lockStun() {
//		if (isStun) {
//			timeStun = 0;
//			startStun = 0;
//			isStun = false;
//		}
//	}
//	
//	public void setStunAction() {
//		if (isMoveBack || isDodge) {
//			isStun = false;
//			return;
//		}
//		startStun = System.currentTimeMillis();
//		switch (mState) {
//		case MOVE:
//			resetAnimation(160);
//			handler.setVelocityX(init_velocity / 2);
//			break;
//		case BEAT:
//			resetAnimation(160);
//			break;
//		case FIRE:
//			resetAnimation(deepCopy(durationFireSkill));
//			break;
//
//		default:
//			break;
//		}
//	}

//	public long[] deepCopy(long... pDuration) {
//		int size = pDuration.length;
//		long[] duration = new long[size];
//		for (int i = 0; i <size; i++) {
//			duration[i] = pDuration[i] * 2;
//		}
//		return duration;
//	}
//	
//	public void resetStunAction() {
//		isStun = false;
//		startStun = 0;
//		timeStun = 0;
//		if (mState == FlatDragonStates.DIE)
//			return;
//
//		switch (mState) {
//		case MOVE:
//			resetAnimation(80);
//			handler.setVelocityX(init_velocity);
//			break;
//		case BEAT:
//			if (getTextureRegion() != mAttackTextureRegion)
//				updateTextureRegion(mAttackTextureRegion, true);
//			resetAnimation(80);
//			break;
//		case FIRE:
//			if (getTextureRegion() != mAttackTextureRegion)
//				updateTextureRegion(mAttackTextureRegion, true);
//			resetAnimation(durationFireSkill);
//			break;
//
//		default:
//			break;
//		}
//	}
//	
	public void setAttackBasic() {
		this.attackBasic = this.agility;
	}

	public boolean isShot(final float pX, final float pY) {
		float x = xContain + getX();
		float y = yContain + getY();

		if ((pX > x && pX < x + widthContain)
				&& (pY > y && pY < y + heightContain) && !isDodge
				&& !isMoveBack) {
			if (mState == FlatDragonStates.MOVE)
				countShot++;
			return true;
		}
		return false;
	}

	protected void createContain() {
		xContain = 40;
		yContain = 10;

		widthContain = 60;
		heightContain = 150;
	}

	public void reduceBlood(float blood) {
		super.reduceBlood(blood);
		if (countShot >= 5 && hitPoints > 0 && !isMoveBack
				&& mState != FlatDragonStates.FIRE) {
			this.isAllowChangeStatus = true;
			mLastState = mState;
			mState = FlatDragonStates.DODGE;
			countShot = 0;
		}
	}

	public void setLastState(FlatDragonStates pState) {
		mLastState = pState;
	}

	public FlatDragonStates getLastState() {
		return mLastState;
	}

	private void dodge(int index) {
		stopAnimation(index);
		handler.setEnabled(false);

		float target = MathUtils.random(5, 300);
		float y = getY();
		float time = Math.abs(y - target) / 300;
		countDodge = (long) (time * 1000);

		MoveModifier modifier = new MoveModifier(time, this.getX(),
				this.getX(), y, target);
		registerEntityModifier(modifier);

		countShot = 0;
		countTimeDodge = System.currentTimeMillis();
		isDodge = true;
		mState = FlatDragonStates.DODGE;
	}

	public void setFireSkill(boolean isFireSkill) {
		isFire = isFireSkill;
	}

	public void stopAttack(boolean isFireSkill) {
		isAttack = isFireSkill;
	}

	public void moveBack(final float pX, final float pY) {
		if (isDodge || isMoveBack)
			return;
		xBack = pX;
		yBack = pY;
		mState = FlatDragonStates.MOVE_BACK;
		isAllowChangeStatus = true;
	}

	private void moveBack() {
		if (changeTiledTextureRegion(FlatDragonStates.MOVE_BACK))
			updateTexture(mTextureRegionMove, FlatDragonStates.MOVE_BACK);
		stopAnimation(0);
		timeMoveBack = 500;
		if (xBack > 750)
			xBack = 750;
		MoveModifier modifier = new MoveModifier(0.5f, this.getX(), xBack,
				this.getY(), yBack);
		this.registerEntityModifier(modifier);

		handler.setEnabled(false);
		status = Constants.MOVE;
		isMoveBack = true;

	}

	public void updateTexture(TiledTextureRegion pTiledTextureRegion,
			FlatDragonStates pState) {
		stopAnimation();
		updateTextureRegion(pTiledTextureRegion, true);

		if (pState.getIndex() == 0) {
			widthContain = 70;
			heightContain = 130;
		} else {
			widthContain = 85;
			heightContain = 140;
		}
	}

	public void setState(FlatDragonStates pState) {
		this.mState = pState;
	}

	public void move() {
		if (this.getTextureRegion() != mTextureRegionMove)
			updateTextureRegion(mTextureRegionMove, true);

		mState = FlatDragonStates.MOVE;
		this.animate(durationMove);
		status = Constants.MOVE;
		isFire = false;
		handler.setEnabled(true);
		handler.setVelocityX(init_velocity);
	}

	public void beat() {
		if (this.getTextureRegion() != mAttackTextureRegion)
			this.updateTextureRegion(mAttackTextureRegion, true);

		this.animate(durationBeat, 0, 12, true);

		handler.setEnabled(false);
		isAttack = false;
		status = Constants.ATTACK;
		tiledAttack = 10;
		isFire = false;
	}

	public void fire() {

		if (this.getTextureRegion() != mAttackTextureRegion)
			this.updateTextureRegion(mAttackTextureRegion, true);

		this.animate(durationFireSkill, 13, 19, 0, new IAnimationListener() {

			@Override
			public void onAnimationEnd(AnimatedSprite arg0) {
				isFire = true;
				move();
			}
		});

		handler.setEnabled(false);
		status = Constants.ATTACK;
		tiledAttack = 18;
		isFire = false;
	}

	public boolean changeState(FlatDragonStates pState) {
		if (pState == mState)
			return false;
		mState = pState;
		return true;
	}

	private boolean changeTiledTextureRegion(FlatDragonStates pState) {
		if (pState.getIndex() != mState.getIndex())
			return true;
		return false;
	}

	public void die() {
		this.setVisible(false);
		mState = FlatDragonStates.DIE;
	}

	public FlatDragonStates getState() {
		return mState;
	}

	public int getTiledAttack() {
		return tiledAttack;
	}

	public boolean isFire() {
		return isFire;
	}

	public static enum FlatDragonStates {
		MOVE(0), MOVE_BACK(0), BEAT(1), FIRE(1), DIE(2), DODGE(3);

		private int index;

		private FlatDragonStates(final int pTiledTextureRegion) {
			this.index = pTiledTextureRegion;
		}

		private int getIndex() {
			return index;
		}
	}
}
